package com.xin.di.uav.applet.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xin.di.uav.applet.mapper.CommodityMapper;
import com.xin.di.uav.applet.po.Business;
import com.xin.di.uav.applet.rest.BusinessRest;
import com.xin.di.uav.applet.service.ICommodityService;
import com.xin.di.uav.common.enums.CommodityStatusEnum;
import com.xin.di.uav.common.request.operate.CommodityReq;
import com.xin.di.uav.common.response.operational.CommodityRes;
import com.xin.di.uav.common.utils.BeanUtil;
import com.xin.di.uav.common.utils.RespJsonPageData;
import com.xin.di.uav.common.utils.Rs;
import com.xin.di.uav.user.order.po.Product;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author LTQ
 * @since 2023-12-07
 */
@Service
@RequiredArgsConstructor
public class CommodityServiceImpl extends ServiceImpl<CommodityMapper, Product> implements ICommodityService {

    private final CommodityMapper commodityMapper;

    private final BusinessRest businessRest;
    private static final Integer CONST_NUM = 0;
    private static final Integer NAME_CHECK = 15;
    private static final String AMOUNT_CHECK = "^[1-9]\\d*$";

    @Override
    public List<Product> getByBusinessId(String businessId) {
        QueryWrapper<Product> commodityQueryWrapper = new QueryWrapper<>();
        commodityQueryWrapper.eq("business_id", businessId);
        commodityQueryWrapper.eq("status", CommodityStatusEnum.GROUNDING.getValue());
        commodityQueryWrapper.orderByDesc("update_time");
        return commodityMapper.selectList(commodityQueryWrapper);
    }

    @Override
    public Product getById(String id) {
        QueryWrapper<Product> commodityQueryWrapper = new QueryWrapper<>();
        commodityQueryWrapper.eq("id", id);
        commodityQueryWrapper.eq("status", CommodityStatusEnum.GROUNDING.getValue());
        return commodityMapper.selectOne(commodityQueryWrapper);
    }

    @Override
    public RespJsonPageData<CommodityRes> getPageCommodity(CommodityReq commodityReq) {
        LambdaQueryWrapper<Product> wrapper = Wrappers.lambdaQuery();
        if (!ObjectUtils.isEmpty(commodityReq.getStatus()) && CommodityStatusEnum.SOLD_OUT.getValue().equals(commodityReq.getStatus())) {
            wrapper.like(StringUtils.isNotBlank(commodityReq.getName()), Product::getName, commodityReq.getName())
                    .eq(StringUtils.isNotBlank(commodityReq.getBusinessId()), Product::getMerchantId, commodityReq.getBusinessId())
                    .eq(Product::isStatus, commodityReq.getStatus())
                    .orderByDesc(Product::getCreatedAt);
        } else {
            wrapper.like(StringUtils.isNotBlank(commodityReq.getName()), Product::getName, commodityReq.getName())
                    .eq(StringUtils.isNotBlank(commodityReq.getBusinessId()), Product::getMerchantId, commodityReq.getBusinessId())
                    .eq(!ObjectUtils.isEmpty(commodityReq.getStatus()), Product::isStatus, commodityReq.getStatus())
                    .orderByDesc(Product::getCreatedAt);
        }
        Page<Product> commodityPageList = commodityMapper.selectPage(new Page<>(commodityReq.getPage(), commodityReq.getSize()), wrapper);
        List<CommodityRes> commodityResList = BeanUtil.copyProperties(commodityPageList.getRecords(), CommodityRes.class);
        if (!CollectionUtils.isEmpty(commodityResList)) {
            Set<String> businessIdSet = commodityPageList.getRecords().stream().map(Product::getMerchantId).collect(Collectors.toSet());
            List<Business> businessList = businessRest.getBusinessesByBusinessIds(businessIdSet);
            Map<String, Business> businessMap = businessList.stream().collect(Collectors.toMap(Business::getId, each -> each, (value1, value2) -> value1));
            commodityResList.forEach(commodityRes -> {
                if (!ObjectUtils.isEmpty(businessMap.get(commodityRes.getBusinessId()))) {
                    commodityRes.setBusinessName(businessMap.get(commodityRes.getBusinessId()).getName());
                }
                if (CommodityStatusEnum.SOLD_OUT.getValue().equals(commodityRes.getAmount())) {
                    commodityRes.setStatusName(CommodityStatusEnum.SOLD_OUT.getDesc());
                } else {
                    commodityRes.setStatusName(CommodityStatusEnum.getDesc(commodityRes.getStatus()));
                }
            });
        }
        return RespJsonPageData.success(commodityResList, commodityPageList.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Rs<Integer> save(CommodityReq commodityReq) {
        batchCheckCommodityReq(commodityReq);
        Product commodity = BeanUtil.copyProperties(commodityReq, Product.class);
        commodity.setStatus(true);
        int con = commodityMapper.insert(commodity);
        if (con > CONST_NUM) {
            return Rs.success(CONST_NUM);
        } else {
            return Rs.failed();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Rs<Integer> updateById(CommodityReq commodityReq) {
        if (StringUtils.isBlank(commodityReq.getId())) {
            throw new RuntimeException("商品id不能为空");
        }
        if (ObjectUtils.isEmpty(commodityReq.getStatus())) {
            batchCheckCommodityReq(commodityReq);
        } else {
            if (StringUtils.isBlank(commodityReq.getProcessedBy())) {
                throw new RuntimeException("处理人不能为空");
            }
        }
        Product commodity = BeanUtil.copyProperties(commodityReq, Product.class);
        commodity.setUpdatedAt(new Date());
        int updateCum = commodityMapper.updateById(commodity);
        if (updateCum > CONST_NUM) {
            return Rs.success(CONST_NUM);
        } else {
            return Rs.failed();
        }
    }

    private void batchCheckCommodityReq(CommodityReq commodityReq) {
        if (StringUtils.isBlank(commodityReq.getName())) {
            throw new RuntimeException("商品名称不能为空");
        }
        if (commodityReq.getName().length() > NAME_CHECK) {
            throw new RuntimeException("商品名称长度不能超过15位");
        }
        if (StringUtils.isBlank(commodityReq.getBusinessId())) {
            throw new RuntimeException("关联商家id不能为空");
        }
        if (ObjectUtils.isEmpty(commodityReq.getPrice()) || commodityReq.getPrice().compareTo(BigDecimal.ZERO) == CONST_NUM) {
            throw new RuntimeException("售价不能为空或为0");
        }
        if (ObjectUtils.isEmpty(commodityReq.getSupplyPrice()) || commodityReq.getSupplyPrice().compareTo(BigDecimal.ZERO) == CONST_NUM) {
            throw new RuntimeException("供货价不能为空或为0");
        }
        if (ObjectUtils.isEmpty(commodityReq.getAmount())) {
            throw new RuntimeException("库存数量不能为空");
        }
        if (!commodityReq.getAmount().toString().matches(AMOUNT_CHECK)) {
            throw new RuntimeException("库存数量只能是数字且不能为0");
        }
        if (StringUtils.isBlank(commodityReq.getProcessedBy())) {
            throw new RuntimeException("处理人不能为空");
        }
    }

}
